package com.atguigu.c_designed.m3beheviorModel.b7State;


/**
 * 状态模式( State Pattern ) 也称为状态机模式(State Machine Pattern), 是允许对象在内 部状态发生改变时改变它的行为,对象看起来好像修改了它的类，属于行为型模式。

 * 解释：允许对象在内部状态发生改变时改变它的行为，对象看起来好像修改了它的类。
 * 状态模式中类的行为是由状态决定的，不同的状态下有不同的行为。其意图是让一个对象在 其内部改变的时候,其行为也随之改变。
 * 状态模式核心是状态与行为绑定,不同的状态对应不 同的行为。
 */




/**
 * 18.7.状态模式的优缺点
 * 优点：
 *
 * 1、结构清晰：将状态独立为类，消除了冗余的if...else或 switch...case语 句 ，使代码更加简洁, 提高系统可维护性；
 * 2、将状态转换显示化：通常的对象内部都是使用数值类型来定义状态，状态的切换是通过赋值 进行表现,不够直观
 * 而使用状态类，在切换状态时,是以不同的类进行表示，转换目的更加 明确；
 * 3、状态类职责明确且具备扩展性。
 * 缺点：
 * 1、类膨胀：如果一个事物具备很多状态，则会造成状态类太多；
 * 2、状态模式的结构与实现都较为复杂，如果使用不当将导致程序结构和代码的混乱；
 * 3、状态模式对开闭原则的支持并不太好，对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,
 * 否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。
 */
public class StateClient {
    public static void main(String[] args) {
        AppContext appContext = new AppContext();
        appContext.favorite();
        appContext.comment("我是来评论的。。。");
    }
}

class AppContext {
    public  static final UserState STATE_LOGIN = new LoginState();
    public  static final UserState STATE_UN_LOGIN = new UnLoginState();

    private UserState currentState =STATE_UN_LOGIN;
    {
       STATE_LOGIN.setContext(this);
        STATE_UN_LOGIN.setContext(this);
    }

    public void setCurrentState(UserState currentState) {
        this.currentState = currentState;
    }
    public UserState getCurrentState(){
        return this.currentState;
    }

    public void favorite(){
        this.currentState.favorite();
    }

    public void comment(String comment){
        this.currentState.comment(comment);
    }

}

abstract class UserState {
    protected AppContext context;

    public void setContext(AppContext context) {
        this.context = context;
    }

    public abstract void favorite();
    public abstract void comment(String comment);
}
class UnLoginState extends UserState {

    @Override
    public void favorite() {
        switch2login();
        this.context.getCurrentState().favorite();
    }

    @Override
    public void comment(String comment) {
        switch2login();
        this.context.getCurrentState().comment(comment);
    }
    private void switch2login(){
        System.out.println("跳转到登录页！");
        this.context.setCurrentState(AppContext.STATE_LOGIN);
    }
}

class LoginState extends UserState {

    @Override
    public void favorite() {
        System.out.println("收藏成功！");
    }

    @Override
    public void comment(String comment) {
        System.out.println(comment);
    }
}
